
#include <stdarg.h>
#include <stdio.h>
#include <winsock.h>
#include "public_define.h"

#ifndef _FTPD_H
#define _FTPD_H


typedef struct ftpd_arg_s{
	SOCKET ctrl_ssock;
	struct sockaddr_in client_addr;
}ftpd_arg_t;

typedef struct ftp_cmd_s{
	int cmdfd;
	char cmdstr[CMDSTR_SIZE];
}ftp_cmd_t;

typedef int login_status_t;		//-1: fail(not logined), 0:mid-status, 1:logined

typedef struct transmode_s{
	char type;				//type in {'A'_ASCII, 'N'_NOTPRINTable, 'I'_IMAGE}, DEFAULT: 'A' or 'N'	
	char mode;				//mode in {'S'_STREAM},	DEFAULT: 'A'
	char stru;				//structure in {'F'_FILE, 'R'_RECORD}, DEFAULT: 'F'
	bool pasv;				//Postive || Passive mode
}transmode_t;

typedef struct dt_conn_s{
	bool				dt_est;		//data connection established?
	SOCKET				dt_msock;
	SOCKET				dt_ssock;
	int					dt_clt_len;
	struct sockaddr_in	dt_clt_adr;
	transmode_t			*transmode;
}dt_conn_t;

typedef struct ctrl_conn_s{
	SOCKET		ctrl_ssock;
	char		*user;
	char		*req_arg;
	char		*response;
}ctrl_conn_t;

typedef struct ftp_path_s{
	char user_pwd[PATH_MAX_LENGTH];				//,							'/' termined
	char absolute_path[PATH_MAX_LENGTH];		//user absolute(sys) path,		 '/' termined;
	char user_root[PATH_MAX_LENGTH];			//user's root in sys path,		non-'/' termined
}ftp_path_t;

extern char	**curr_cmd;
extern ftp_cmd_t ftp_cmd[CURRENT_CMDS];
extern char *Ipaddress;


/*********** api ********************/
void ftpd(void *);

int		ftp_cmd_init();
int		ftp_cmd_analyze( char *recv_buf, char **request_arg);
int		ftpd_cmd_user(ctrl_conn_t *ctrl_conn, login_status_t *login_status);
int		ftpd_cmd_pass(ctrl_conn_t *ctrl_conn, login_status_t *login_status);
int		ftpd_cmd_cwd(ctrl_conn_t *ctrl_conn, ftp_path_t *path);
int		ftpd_cmd_type(ctrl_conn_t *ctrl_conn, transmode_t *transmode);
bool	ftpd_cmd_type_supported(char *type);
int		ftpd_cmd_pasv(ctrl_conn_t *ctrl_conn, transmode_t *);
int		ftpd_cmd_list(ctrl_conn_t *ctrl_conn, dt_conn_t *dt_conn, ftp_path_t *path);
int		ftpd_cmd_size(ctrl_conn_t *ctrl_conn, dt_conn_t *dt_conn,const ftp_path_t *path);
int		ftpd_cmd_port(ctrl_conn_t *ctrl_conn, dt_conn_t *dt_conn);
int		ftpd_cmd_retr(ctrl_conn_t *ctrl_conn, dt_conn_t *dt_conn,const ftp_path_t *path);
int		ftpd_cmd_stor(ctrl_conn_t *ctrl_conn, dt_conn_t *dt_conn,const ftp_path_t *path);
int		ftpd_cmd_syst(ctrl_conn_t *ctrl_conn );
int		ftpd_cmd_pwd(ctrl_conn_t *ctrl_conn, ftp_path_t *path);
int		ftpd_cmd_mdtm(ctrl_conn_t *ctrl_conn, ftp_path_t *path);


int		ftp_response_set(char *tobeset,const int toset, const char *infor);
		// value returned is length of "tobeset", and -1 means error

int		ftp_shadow(char *cmpstr, const char *choice);	//choice is in {"user", "pass", "pwd"}
		//ON RETURN:
		//if "user":(should pass in a pointer point to the user)
		//			0:matched, >0: notmatched , <0: error
		//if "pass":(shold psss in a pointer point to the [PASSWD NAME])
		//			0:matched, >0: notmatched, < 0: error
		//if "rotd": (should passin a pointer point to the user,
		//			**NOTICE ** , this function will change cmpstr to the user's root_dir
		//			0:ok	    <0:	error

char	*ftp_delcrlf(char *arg);
bool	ftp_permission_check(char *user,ftp_path_t *path , char action);	
		//need user name , requested dir or file name(absolute path), action is in ('L'_list, 'R', 'W')
bool	ftp_dest_exist(ftp_path_t *tobetest);
char	*ftp_path_unix2dos(char *pathstr);
int		ftpd_fullstop2comma(char *Ipaddress);
int		ftp_path_makeup(ftp_path_t *path_s, char *pathname);


#endif//_FTPD_H